package com.googlecode.utterlyidle.bindings;

import com.googlecode.totallylazy.Either;
import com.googlecode.totallylazy.Sequence;
import com.googlecode.utterlyidle.Binding;
import com.googlecode.utterlyidle.Bindings;
import com.googlecode.utterlyidle.MatchFailure;
import com.googlecode.utterlyidle.Request;

import static com.googlecode.totallylazy.Left.left;
import static com.googlecode.totallylazy.Right.right;
import static com.googlecode.utterlyidle.bindings.MatchQuality.matchQuality;

public class MatchQualityBindingMatcher implements BindingMatcher {
    private final BindingsMatcher bindingsMatcher;

    public MatchQualityBindingMatcher(BindingsMatcher bindingsMatcher) {
        this.bindingsMatcher = bindingsMatcher;
    }

    @Override
    public Either<MatchFailure, Binding> match(Request request) {
        return bestMatch(request, bindingsMatcher.match(request));
    }

    @Override
    public Either<MatchFailure, Binding> match(Request request, Bindings bindings) {
        return bestMatch(request, bindingsMatcher.match(request, bindings));
    }

    private Either<MatchFailure, Binding> bestMatch(Request request, Either<MatchFailure, Sequence<Binding>> failureOrBindings) {
        if (failureOrBindings.isLeft())
            return left(failureOrBindings.left());
        return right(findBestMatch(request, failureOrBindings.right()));
    }

    private Binding findBestMatch(Request request, final Sequence<Binding> bindings) {
        return bindings.sortBy(matchQuality(request)).head();
    }

}
